﻿using System.Collections.Generic;
using NUnit.Framework;

namespace SellAndBuy.Domain.Core.Tests
{
    /// <summary>
    /// Value Object Tests
    /// </summary>
    [TestFixture]
    public class ValueObjectTests
    {
        [Test]
        public void Creating_New_Value_Object()
        {
            var valueObject = new ValueObject() {SampleIntProperty = 1, SampleStringProperty = "Sample"};

            Assert.AreEqual(1, valueObject.SampleIntProperty);
            Assert.AreEqual("Sample", valueObject.SampleStringProperty);
        }

        [Test]
        public void Two_Null_Value_Objects_Are_Equals()
        {
            ValueObject valueObject1 = null;
            ValueObject valueObject2 = null;

            Assert.AreEqual(true, valueObject1 == valueObject2);
            Assert.AreEqual(false, valueObject1 != valueObject2);
        }

        [Test]
        public void Two_Different_Value_Objects_Are_Not_Equals()
        {
            var valueObject1 = new ValueObject { SampleIntProperty = 1, SampleStringProperty = "Sample" };
            var valueObject2 = new ValueObject { SampleIntProperty = 2, SampleStringProperty = "Sample" };

            Assert.AreEqual(false, valueObject1.Equals(valueObject2));
            Assert.AreEqual(false, valueObject1 == valueObject2);
            Assert.AreEqual(true, valueObject1 != valueObject2);
        }

        [Test]
        public void Two_Value_Objects_With_Same_Properties_Are_Equals()
        {
            var valueObject1 = new ValueObject { SampleIntProperty = 1, SampleStringProperty = "Sample" };
            var valueObject2 = new ValueObject { SampleIntProperty = 1, SampleStringProperty = "Sample" };

            Assert.AreEqual(true, valueObject1.Equals(valueObject2));
            Assert.AreEqual(true, valueObject1 == valueObject2);
            Assert.AreEqual(false, valueObject1 != valueObject2);
        }

        [Test]
        public void Valid_Value_Object_Not_Equals_To_Null_EValue_Object()
        {
            var valueObject1 = new ValueObject { SampleIntProperty = 1, SampleStringProperty = "Sample" };
            ValueObject valueObject2 = null;

            Assert.AreEqual(false, valueObject1.Equals(valueObject2));
            Assert.AreEqual(false, valueObject1 == valueObject2);
            Assert.AreEqual(true, valueObject1 != valueObject2);
        }

        [Test]
        public void Two_Similar_Value_Object_Have_Same_HashCode()
        {
            var valueObject = new ValueObject { SampleIntProperty = 2, SampleStringProperty = "Sample" };
            var valueObjectClone = new ValueObject { SampleIntProperty = 2, SampleStringProperty = "Sample" };

            Assert.AreEqual(valueObjectClone.GetHashCode(), valueObject.GetHashCode());
        }
    }

    internal class ValueObject : ValueObjectBase<ValueObject>
    {
        public string SampleStringProperty { get; set; }
        public int SampleIntProperty { get; set; }
    }
}
